package com.kexio.user.controller;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kexio.auth.annotation.RateLimit;
import com.kexio.auth.annotation.RequiresPermission;
import com.kexio.auth.util.AuthContextUtils;
import com.kexio.common.dto.PageResponse;
import com.kexio.common.dto.Result;
import com.kexio.common.page.PageConverters;
import com.kexio.common.page.PageQuery;
import com.kexio.common.page.PageUtils;
import com.kexio.user.dto.PermissionDTO;
import com.kexio.user.dto.PermissionStatistics;
import com.kexio.user.entity.Permission;
import com.kexio.user.entity.Role;
import com.kexio.user.entity.User;
import com.kexio.user.service.PermissionService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;

/**
 * 权限管理控制器
 * 
 * 提供权限管理的REST API接口，包括：
 * - 权限CRUD操作
 * - 权限树形结构查询
 * - 权限关联查询
 * - 权限状态管理
 * - 权限统计信息
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@RestController
@RequestMapping("/permissions")
@Tag(name = "权限管理", description = "权限管理相关API")
public class PermissionController {
    
    private static final Logger logger = LoggerFactory.getLogger(PermissionController.class);
    
    private final PermissionService permissionService;
    
    public PermissionController(PermissionService permissionService) {
        this.permissionService = permissionService;
    }
    
    // ==================== 基础CRUD操作 ====================
    
    /**
     * 创建权限
     */
    @PostMapping
    @RequiresPermission("permission:create")
    @RateLimit(count = 20, time = 1)
    @Operation(summary = "创建权限", description = "创建新的权限")
    public Result<PermissionDTO> createPermission(
            @Valid @RequestBody PermissionDTO request) {
        
        logger.info("创建权限请求: permissionCode={}, tenantId={}", 
            request.getPermissionCode(), AuthContextUtils.getCurrentTenantId());
        
        request.clearIdsForCreate();
        request.validate();
        
        // 转换DTO到Permission实体
        Permission permission = request.toEntity();
        permission = permissionService.createPermission(permission);
        PermissionDTO permissionDTO = PermissionDTO.fromEntity(permission);
        
        logger.info("创建权限成功: permissionId={}, permissionCode={}", 
            permission.getId(), permission.getCode());
        
        return Result.success("权限创建成功", permissionDTO);
    }
    
    /**
     * 更新权限
     */
    @PutMapping("/{permissionId}")
    @RequiresPermission("permission:update")
    @RateLimit(count = 30, time = 1)
    @Operation(summary = "更新权限信息", description = "更新指定权限的信息")
    public Result<PermissionDTO> updatePermission(
            @Parameter(description = "权限ID") @PathVariable String permissionId,
            @Valid @RequestBody PermissionDTO request) {
        
        logger.info("更新权限请求: permissionId={}, tenantId={}", 
            permissionId, AuthContextUtils.getCurrentTenantId());
        
        // 验证并清理请求数据
        request.validate();
        
        if (!request.hasAnyUpdateFields()) {
            logger.warn("更新权限请求无任何更新内容: permissionId={}", permissionId);
            return Result.error("请提供要更新的内容");
        }
        
        // 转换DTO到Permission实体
        Permission permission = request.toEntity();
        permission = permissionService.updatePermission(permissionId, permission);
        PermissionDTO permissionDTO = PermissionDTO.fromEntity(permission);
        
        logger.info("更新权限成功: permissionId={}, permissionCode={}", 
            permission.getId(), permission.getCode());
        
        return Result.success("权限更新成功", permissionDTO);
    }
    
    /**
     * 删除权限
     */
    @DeleteMapping("/{permissionId}")
    @RequiresPermission("permission:delete")
    @RateLimit(count = 10, time = 1)
    @Operation(summary = "删除权限", description = "删除指定的权限（逻辑删除）")
    public Result<Void> deletePermission(
            @Parameter(description = "权限ID") @PathVariable String permissionId) {
        
        logger.info("删除权限请求: permissionId={}", permissionId);
        
        boolean success = permissionService.deletePermission(permissionId);
        
        if (!success) {
            logger.warn("删除权限失败: permissionId={}", permissionId);
            return Result.error("权限不存在或已被删除");
        }
        
        logger.info("删除权限成功: permissionId={}", permissionId);
        return Result.<Void>success("权限删除成功", null);
    }
    
    /**
     * 获取权限详情
     */
    @GetMapping("/{permissionId}")
    @RequiresPermission("permission:query")
    @Operation(summary = "获取权限详情", description = "获取指定权限的详细信息")
    public Result<PermissionDTO> getPermission(
            @Parameter(description = "权限ID") @PathVariable String permissionId) {
        
        logger.debug("获取权限详情请求: permissionId={}", permissionId);
        
        Permission permission = permissionService.getPermissionById(permissionId);
        
        if (permission == null) {
            logger.warn("权限不存在: permissionId={}", permissionId);
            return Result.error("权限不存在");
        }
        
        PermissionDTO permissionDTO = PermissionDTO.fromEntity(permission);
        
        logger.debug("获取权限详情成功: permissionId={}, permissionCode={}", 
            permission.getId(), permission.getCode());
        
        return Result.success("获取成功", permissionDTO);
    }
    
    // ==================== 权限列表查询 ====================
    
    /**
     * 分页查询权限
     */
    @GetMapping
    @RequiresPermission("permission:query")
    @Operation(summary = "分页查询权限", description = "根据条件分页查询权限列表")
    public Result<PageResponse<PermissionDTO>> queryPermissions(
            @Parameter(description = "权限类型") @RequestParam(required = false) String permissionType,
            @Parameter(description = "权限编码") @RequestParam(required = false) String permissionCode,
            @Parameter(description = "权限名称") @RequestParam(required = false) String permissionName,
            @Parameter(description = "关联菜单ID") @RequestParam(required = false) String menuId,
            @Parameter(description = "状态") @RequestParam(required = false) Integer status,
            @Parameter(description = "分页参数") PageQuery pageQuery) {
        
        logger.debug("分页查询权限请求: current={}, size={}, tenantId={}", 
            (pageQuery != null ? pageQuery.getCurrent() : null), (pageQuery != null ? pageQuery.getSize() : null), AuthContextUtils.getCurrentTenantId());
        
        long current = PageUtils.current(pageQuery);
        long size = PageUtils.size(pageQuery);
        // 使用带条件的分页查询（透传过滤条件）
        Page<Permission> permissionPage =
            permissionService.getPermissionPage(current, size, permissionCode, permissionName, permissionType, status, menuId);
        
        // 转换为DTO
        PageResponse<PermissionDTO> response = PageConverters.map(
            permissionPage.getRecords(),
            permissionPage.getTotal(),
            permissionPage.getCurrent(),
            permissionPage.getSize(),
            PermissionDTO::fromEntity
        );
        
        logger.debug("分页查询权限成功: total={}, current={}, size={}", 
            permissionPage.getTotal(), permissionPage.getCurrent(), permissionPage.getSize());
        
        return Result.success("查询成功", response);
    }
    
    /**
     * 获取所有权限
     */
    @GetMapping("/all")
    @RequiresPermission("permission:query")
    @Operation(summary = "获取所有权限", description = "获取当前租户下的所有权限")
    public Result<List<PermissionDTO>> getAllPermissions() {
        
        logger.debug("获取所有权限请求: tenantId={}", AuthContextUtils.getCurrentTenantId());
        
        List<Permission> permissions = permissionService.getPermissionsByTenant();
        
        // 转换为DTO
        List<PermissionDTO> permissionDTOs = PageConverters.mapList(permissions, PermissionDTO::fromEntity);
        
        logger.debug("获取所有权限成功: count={}", permissions.size());
        
        return Result.success("获取成功", permissionDTOs);
    }
    
    /**
     * 根据权限类型获取权限列表
     */
    @GetMapping("/type/{permissionType}")
    @RequiresPermission("permission:query")
    @Operation(summary = "根据类型获取权限", description = "根据权限类型获取权限列表")
    public Result<List<PermissionDTO>> getPermissionsByType(
            @Parameter(description = "权限类型") @PathVariable String permissionType) {
        
        logger.debug("根据类型获取权限请求: permissionType={}, tenantId={}", 
            permissionType, AuthContextUtils.getCurrentTenantId());
        
        List<Permission> permissions = permissionService.getPermissionsByType(permissionType);
        
        // 转换为DTO
        List<PermissionDTO> permissionDTOs = PageConverters.mapList(permissions, PermissionDTO::fromEntity);
        
        logger.debug("根据类型获取权限成功: permissionType={}, count={}", 
            permissionType, permissions.size());
        
        return Result.success("获取成功", permissionDTOs);
    }
    
    // ==================== 权限树形结构 ====================
    
    /**
     * 获取权限树
     */
    @GetMapping("/tree")
    @RequiresPermission("permission:query")
    @Operation(summary = "获取权限树", description = "获取权限的树形结构")
    public Result<List<PermissionDTO>> getPermissionTree() {
        
        logger.debug("获取权限树请求: tenantId={}", AuthContextUtils.getCurrentTenantId());
        
        List<Permission> permissions = permissionService.getPermissionTree();
        
        // 转换为DTO - 在Service层已构建树形结构
        List<PermissionDTO> permissionTree = PageConverters.mapList(permissions, PermissionDTO::fromEntity);
        
        logger.debug("获取权限树成功: count={}", permissions.size());
        
        return Result.success("获取成功", permissionTree);
    }
    
    /**
     * 获取子权限
     */
    @GetMapping("/{permissionId}/children")
    @RequiresPermission("permission:query")
    @Operation(summary = "获取子权限", description = "获取指定权限的直接子权限")
    public Result<List<PermissionDTO>> getChildPermissions(
            @Parameter(description = "父权限ID") @PathVariable String permissionId) {
        
        logger.debug("获取子权限请求: parentPermissionId={}", permissionId);
        
        // Sa-Token架构下不支持权限层级关系，返回空列表
        logger.info("获取子权限请求已忽略: parentPermissionId={} - Sa-Token架构下权限为扁平化管理", permissionId);
        List<Permission> childPermissions = Collections.emptyList();
        
        // 转换为DTO
        List<PermissionDTO> permissionDTOs = PageConverters.mapList(childPermissions, PermissionDTO::fromEntity);
        
        logger.debug("获取子权限完成: parentPermissionId={}, count={} (Sa-Token架构下固定返回空列表)", 
            permissionId, childPermissions.size());
        
        return Result.success("获取成功", permissionDTOs);
    }
    
    // ==================== 权限状态管理 ====================
    
    /**
     * 更新权限状态
     */
    @PutMapping("/{permissionId}/status")
    @RequiresPermission("permission:update")
    @RateLimit(count = 30, time = 1)
    @Operation(summary = "更新权限状态", description = "启用或禁用指定权限")
    public Result<Void> updatePermissionStatus(
            @Parameter(description = "权限ID") @PathVariable String permissionId,
            @Parameter(description = "状态：1-启用，0-禁用") @RequestParam Integer status) {
        
        logger.info("更新权限状态请求: permissionId={}, status={}", permissionId, status);
        
        // 验证状态值
        if (status == null || (status != 0 && status != 1)) {
            logger.warn("权限状态值无效: permissionId={}, status={}", permissionId, status);
            return Result.error("状态值必须是0或1");
        }
        
        // 实现状态更新逻辑
        boolean success = permissionService.updatePermissionStatus(permissionId, status);
        if (success) {
            // 记录审计日志
            logger.info("权限状态更新成功: permissionId={}, status={}, operator={}", 
                      permissionId, status, "SYSTEM");
        }
        
        if (!success) {
            logger.warn("更新权限状态失败: permissionId={}", permissionId);
            return Result.error("权限不存在或更新失败");
        }
        
        logger.info("更新权限状态成功: permissionId={}, status={}", permissionId, status);
        return Result.<Void>success("权限状态更新成功", null);
    }
    
    // ==================== 权限关联管理 ====================
    
    /**
     * 获取权限关联的角色
     */
    @GetMapping("/{permissionId}/roles")
    @RequiresPermission("permission:query")
    @Operation(summary = "获取权限关联的角色", description = "获取拥有指定权限的角色列表")
    public Result<List<String>> getPermissionRoles(
            @Parameter(description = "权限ID") @PathVariable String permissionId) {
        
        logger.debug("获取权限关联角色请求: permissionId={}", permissionId);
        
        List<Role> roles = permissionService.getPermissionRoles(permissionId);
        
        // 转换为角色ID列表（与实体一致的 String 类型）
        List<String> roleIds = roles.stream()
                .map(Role::getId)
                .collect(Collectors.toList());
        
        logger.debug("获取权限关联角色成功: permissionId={}, roleCount={}", 
            permissionId, roleIds.size());
        
        return Result.success("获取成功", roleIds);
    }
    
    /**
     * 获取权限关联的用户
     */
    @GetMapping("/{permissionId}/users")
    @RequiresPermission("permission:query")
    @Operation(summary = "获取权限关联的用户", description = "获取拥有指定权限的用户列表")
    public Result<List<String>> getPermissionUsers(
            @Parameter(description = "权限ID") @PathVariable String permissionId) {
        
        logger.debug("获取权限关联用户请求: permissionId={}", permissionId);
        
        List<User> users = permissionService.getPermissionUsers(permissionId);
        
        // 转换为用户ID列表
        List<String> userIds = users.stream()
                .map(User::getId)
                .collect(Collectors.toList());
        
        logger.debug("获取权限关联用户成功: permissionId={}, userCount={}", 
            permissionId, userIds.size());
        
        return Result.success("获取成功", userIds);
    }
    
    // ==================== 权限统计 ====================
    
    /**
     * 获取权限统计信息
     */
    @GetMapping("/statistics")
    @RequiresPermission("permission:query")
    @Operation(summary = "获取权限统计信息", description = "获取权限的统计数据")
    public Result<PermissionStatistics> getPermissionStatistics() {
        
        logger.debug("获取权限统计信息请求: tenantId={}", AuthContextUtils.getCurrentTenantId());
        
        // 实现权限统计逻辑
        PermissionStatistics statistics = new PermissionStatistics();
        List<Permission> allPermissions = permissionService.getPermissionsByTenant();
        if (allPermissions == null) {
            allPermissions = new java.util.ArrayList<>();
        }
        statistics.setTotalPermissions(allPermissions.size());
        
        long enabledCount = allPermissions.stream()
                .filter(p -> Integer.valueOf(1).equals(p.getStatus()))
                .count();
        statistics.setEnabledPermissions((int) enabledCount);
        statistics.setDisabledPermissions(allPermissions.size() - (int) enabledCount);
        
        // 按类型统计
        long opCount = allPermissions.stream()
                .filter(p -> "OP".equals(p.getType()))
                .count();
        long resourceCount = allPermissions.stream()
                .filter(p -> "RESOURCE".equals(p.getType()))
                .count();
        long apiCount = allPermissions.stream()
                .filter(p -> "API".equals(p.getType()))
                .count();
                
        statistics.setOperationPermissions((int) opCount);
        statistics.setResourcePermissions((int) resourceCount);
        statistics.setApiPermissions((int) apiCount);
        
        logger.debug("获取权限统计信息成功: total={}", statistics.getTotalPermissions());
        
        return Result.success("获取成功", statistics);
    }
    
    /**
     * 获取菜单权限映射
     */
    @GetMapping("/menu-permission-map")
    @RequiresPermission("permission:query")
    @Operation(summary = "获取菜单权限映射", description = "获取所有菜单的权限映射关系，用于前端按菜单分组显示")
    public Result<Map<String, List<PermissionDTO>>> getMenuPermissionMap() {
        
        logger.debug("获取菜单权限映射请求: tenantId={}", AuthContextUtils.getCurrentTenantId());
        
        Map<String, List<Permission>> menuPermissionMap = permissionService.getMenuPermissionMap();
        
        // 转换为DTO
        Map<String, List<PermissionDTO>> result = menuPermissionMap.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> PageConverters.mapList(entry.getValue(), PermissionDTO::fromEntity)
                ));
        
        logger.debug("获取菜单权限映射成功: menuCount={}", result.size());
        
        return Result.success("获取成功", result);
    }
}
